from django.shortcuts import render_to_response, HttpResponseRedirect
from django.template import RequestContext
from readers.models import * 
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.views.generic import list_detail
from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from django.db.models import F
from books.forms import BookForm
from django.core.context_processors import csrf

from django.core.mail import EmailMessage
from msgs.tasks import ReservingNotification

def book_add(request):
	if request.method == 'POST':
		bform = BookForm(request.POST)
		if bform.is_valid():
			bform.save()
		return HttpResponseRedirect('/books/add/')

	else:
		bform = BookForm()
	
	context = { 'form': bform }
	context.update(csrf(request))

	return render_to_response('books/book_add.html',
		context,
		context_instance=RequestContext(request))

def book_index(request):
	'''
	Book index and directory
	'''
	try:
		kword = request.GET['w']
		mbooks = Book.objects.filter(title__icontains=kword)
	except KeyError:
		mbooks = Book.objects.all()

	pag = Paginator(mbooks, 13)

	try:
		p = int(request.GET.get('p', '1'))
	except ValueError:
		p = 1

	try:
		books = pag.page(p)
	except (EmptyPage, InvalidPage):
		books = pag.page(pag.num_pages)

	template = 'books/book_index.html'
	context = {
		'books': books,
	}

	return render_to_response(template, context, RequestContext(request))

def book_detail(request, book_id):
	'''
	Book basic info. and profile
	'''
	book = get_object_or_404(Book, pk=book_id)
	try:
		book_profile = book.bookprofile
		books_reserved = book_profile.reserving_set.filter(status='C')
		books_read = book_profile.reading_set.filter(status="C")
	except:
		book_profile = None
		books_read = []
		books_reserved = []
	
	# there are 2 kinds of status code:
	#	2      : give back
	#	1      : reserve
	#	0      : cancel reserve
	try:
		r = int(request.GET.get('r'))
		if r == 0:
			book_profile.num_reserving = F('num_reserving') - 1 # update: +1
			book_profile.num_availabe = F('num_available') + 1
			book_profile.save()
			reserved = Reserving.objects.get(user_reserving=request.user.userprofile, book_reserved=book_profile, status='C')
			reserved.status = 'B'
			reserved.save()
		if r == 1:
			book_profile.num_reserving = F('num_reserving') + 1 # update: +1
			book_profile.num_availabe = F('num_available') - 1
			book_profile.save()

			# get or create a reserving item
			try:
				read = Reading.objects.get(book_read=book_profile, user_reading=request.user.userprofile, status='C')
			except Reading.DoesNotExist:
				reserved = Reserving.objects.create(user_reserving=request.user.userprofile, book_reserved=book_profile, status='C')
				
				html_content = '<p>[%s] <a href="http://localhost:8000/msgs/?i=%d">Check it</a></p>' % (book_profile.book.title, reserved.id)
				email_msg = EmailMessage('Reserving', html_content, 'wlxku123@163.com', ['wlxku123@gmail.com'])
				email_msg.content_subtype = 'html'
				res = ReservingNotification.delay(email_msg)
				if res.successful():
					return HttpResponseRedirect('/books/')
		if r == 2:
			reading = Reading.objects.get(book_read=book_profile, user_reading=request.user.userprofile, status='C') 
			# set the reading status to False/0, means that
			# the user wanna give it back
			reading.status = 'B' # means Break
			reading.save()
			book_profile.num_available = F('num_available') + 1
			book_profile.save()

		next = request.GET.get('next', '/books/')
		return HttpResponseRedirect(next)
	except: # except (ValueError, TypeError):
		pass

	return list_detail.object_detail(
		request,
		queryset = Book.objects.all(),
		template_name = 'books/book_detail.html',
		template_object_name = 'book',
		extra_context = {
			'book_profile': book_profile,
			'books_read': books_read,
			'books_reserved': books_reserved
		},
		object_id = book_id,
	)
